# 打开网页
import random
import re
import time

import cv2
import requests
from selenium.webdriver import ActionChains
from setting import *


def download_slider_bg(driver, element_selector, save_path="slider_bg.png"):
    """
    使用 Selenium 获取 background-image 图片并下载保存。
    :param driver: Selenium WebDriver 实例
    :param element_selector: 目标元素的 CSS 选择器（如 '#slideBg'）
    :param save_path: 图片保存路径
    :return: 保存的图片路径
    """
    elem = driver.find_element("css selector", element_selector)
    bg_style = elem.get_attribute("style")

    # 正则提取 background-image 的 URL
    match = re.search(r'background-image:\s*url\(["\']?(.*?)["\']?\);', bg_style)
    if not match:
        raise ValueError("未找到 background-image URL")

    image_url = match.group(1)
    # 若图片URL被 HTML 实体转义，需要反转义
    image_url = image_url.replace("&amp;", "&")

    # 下载并保存图片
    response = requests.get(image_url)
    if response.status_code == 200:
        with open(save_path, "wb") as f:
            f.write(response.content)
        return save_path
    else:
        raise IOError(f"图片下载失败，状态码: {response.status_code}")
def get_track(distance):
    """
    根据距离生成轨迹（列表），模拟人手加速减速过程
    """
    track = []
    current = 0
    mid = distance * 3 / 5  # 前段加速，后段减速
    t = 0.2
    v = 0

    while current < distance:
        if current < mid:
            a = random.uniform(2.0, 4.0)  # 加速度
        else:
            a = -random.uniform(3.0, 5.0)  # 减速度
        v0 = v
        v = v0 + a * t
        move = v0 * t + 0.5 * a * t * t
        move = round(move)
        current += move
        track.append(move)

    # 回退一点，模拟误操作
    for _ in range(3):
        track.append(-random.randint(1, 3))
        track.append(random.randint(1, 3))

    return track


def drag_captcha_by_selenium(driver, slider_element, distance):
    """
    模拟人手拖动滑块
    :param driver: selenium webdriver 对象
    :param slider_element: 需要拖动的滑块元素
    :param distance: 拖动的总距离（单位：像素）
    """

    # 获取滑动轨迹
    track = get_track(distance)

    # 点击并按住滑块
    ActionChains(driver).click_and_hold(slider_element).perform()
    time.sleep(random.uniform(0.2, 0.5))

    # 按轨迹移动
    for x in track:
        ActionChains(driver).move_by_offset(xoffset=x, yoffset=random.uniform(-1, 1)).perform()
        time.sleep(random.uniform(0.01, 0.03))

    # 稳定一会
    time.sleep(random.uniform(0.1, 0.3))
    ActionChains(driver).release().perform()

def drag_captcha_by_js(driver, distance):
    """
    使用 JavaScript 注入方式模拟滑动滑块
    :param driver: Selenium webdriver
    :param slider_element: 滑块 WebElement
    :param distance: 需要滑动的距离
    """

    # 构造 JS 拖动逻辑（触发 mousedown, mousemove, mouseup）
    with open(JS_PATH, mode="r", encoding='utf-8')as f:
        js_code =f.read()

        # 替换距离
        js_code= js_code.replace("标识标识标识",str(distance))

    # 执行注入的 JS
    return driver.execute_script(js_code)





def _tran_canny(img):
    """图像边缘提取（灰度 + 模糊 + Canny）"""
    if len(img.shape) == 3:
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    else:
        gray = img
    blurred = cv2.GaussianBlur(gray, (5, 5), 0)
    edges = cv2.Canny(blurred, 50, 150)
    return edges

def detect_displacement(img_slider_path, img_background_path, save_path="output.png"):
    """检测滑块缺口位置并保存标记图"""
    # 读取图像
    slider = cv2.imread(img_slider_path)
    background = cv2.imread(img_background_path)

    if slider is None or background is None:
        raise ValueError("图像加载失败，请检查路径")

    # 边缘检测
    slider_edge = _tran_canny(slider)
    background_edge = _tran_canny(background)

    # 模板匹配
    res = cv2.matchTemplate(background_edge, slider_edge, cv2.TM_CCOEFF_NORMED)
    _, max_val, _, max_loc = cv2.minMaxLoc(res)

    # print(f"匹配得分：{max_val:.4f}")
    # print(f"缺口位置：{max_loc}")

    # 在原图中标记缺口位置
    h, w = slider_edge.shape
    top_left = max_loc
    bottom_right = (top_left[0] + w, top_left[1] + h)

    marked_image = background.copy()
    cv2.rectangle(marked_image, top_left, bottom_right, (0, 0, 255), 2)

    # 保存为新图像
    cv2.imwrite(save_path, marked_image)
    print(f"标记图已保存为：{save_path}")

    mid =int((top_left[0] +bottom_right[0])/2)
    return int ((mid -110)*(341/672))

def crop_and_save(image_path, coord1, coord2, save_path):
    """
    根据两组坐标裁剪图片并保存

    参数:
    - image_path: 原图路径 (str)
    - coord1: 第一个坐标 (x1, y1) 元组或列表
    - coord2: 第二个坐标 (x2, y2) 元组或列表
    - save_path: 裁剪后图片保存路径 (str)
    """

    # 读取图片
    img = cv2.imread(image_path)
    if img is None:
        raise ValueError("图片加载失败，请检查路径")

    x1, y1 = coord1
    x2, y2 = coord2

    # 确保坐标是左上和右下
    x_min, x_max = sorted([x1, x2])
    y_min, y_max = sorted([y1, y2])

    # 裁剪
    cropped = img[y_min:y_max, x_min:x_max]

    # 保存裁剪后的图片
    cv2.imwrite(save_path, cropped)
    print(f"裁剪图片已保存到: {save_path}")
    return  save_path
# 示例调用
if __name__ == "__main__":
    # x = detect_displacement("img2.png", "img1.png", save_path="marked_gap.png")
    # print(f"滑块应该移动到的位置 x = {x}")
    crop_and_save("img.png", (130, 480), (270, 630), "cropped.png")